
-module(gateway).

-export([start/2, start/1]).

-include("common.hrl").
-include("pp.hrl").

start([Port, MaxPlayers])
  when is_atom(Port),
       is_atom(MaxPlayers) ->
    Port1 = list_to_integer(atom_to_list(Port)),
    Max = list_to_integer(atom_to_list(MaxPlayers)),
    start(Port1, Max).

start(Port, MaxPlayers) ->
    io:format("gateway:start(~w, ~w)~n",
              [Port, MaxPlayers]),
    pg2:create(?GAME_SERVERS),
    io:format("Waiting for game servers...~n"),
    
    case wait_for_game_servers() of
        ok ->
            F = fun(Sock) -> handoff(Sock, MaxPlayers) end,
            tcp_server:start_raw_server(Port, F, 10240, 10240),
            io:format("game servers found.~n")
    end.

find_server(MaxPlayers) ->
    case util:get_random_pid(?GAME_SERVERS) of
        {ok, Pid} when is_pid(Pid) ->
            {_Time, {Host, Port}} = timer:tc(gen_server, call, [Pid, 'WHERE']),
            Count = gen_server:call(Pid, 'USER COUNT'),
            if
                Count < MaxPlayers ->
                    %%io:format("~s:~w: ~w players~n", [Host, Port, Count]),
                    {list_to_binary(Host), Port};
                true ->
                    io:format("~s:~w is full...~n", [Host, Port]),
                    find_server(MaxPlayers)
            end;
        Any ->
            Any
    end.

handoff(Socket, Max) ->
    {Host, Port} = find_server(Max),
    ok = ?tcpsend(Socket, #goto{ host = Host, port = Port }),
    timer:sleep(2000),
    ok = gen_tcp:close(Socket).

wait_for_game_servers() ->
    case pg2:get_members(?GAME_SERVERS) of
        [] ->
            timer:sleep(2000),
            wait_for_game_servers();
        _ ->
            ok
    end.